package com.zgroup.services

import com.zgroup.common.CheckUtils
import com.zgroup.common.CipherUtils
import java.text.SimpleDateFormat

class ScaffoldService extends DynamicService {
  boolean transactional = true

  def getProperty(params) {
    def loader = Thread.currentThread().getContextClassLoader()
    def domain = Class.forName("com.zgroup.domain.${params.property}", true, loader)
    def obj = domain.get(params.id)
    if (obj == null) {
      obj = domain.newInstance()
    }

    return obj
  }

  def save(params) {
    def loader = Thread.currentThread().getContextClassLoader()
    def domain = Class.forName("com.zgroup.domain.${params.property}", true, loader)
    def property
    if (CheckUtils.isEmpty(params.id)) {
      property = domain.newInstance()
    } else {
      property = domain.get(params.id)
    }
    if (params.password) {
      params.password = CipherUtils.md5(params.password)
    }
    property.properties = params
    if (!property.save()) {
      property.errors.each {
        println it
      }
      return false;
    }
    return true;
  }

  def remove(params) {
    def obj = getProperty(params)
    obj.delete()
  }

  def paginateList(params) {
    if (params.custom) {
      return "${params.property}Service".paginateList(params);
    }
    if (!params.offset) {
      params.offset = 0
    }
    if (!params.max) {
      params.max = 10
    }
    if (!params.sort) {
      params.sort = "dateCreated"
    }
    if (!params.order) {
      params.order = "desc"
    }
    def paginateParams = [:]
    paginateParams.offset = params.offset
    paginateParams.max = params.max
    paginateParams.sort = params.sort
    paginateParams.order = params.order

    def query = buildWhereSql(params)
    def loader = Thread.currentThread().getContextClassLoader()
    def domain = Class.forName("com.zgroup.domain.${params.property}", true, loader)
    return paginateList(query.sql, query.positionalParams, paginateParams, domain)
  }

  def buildWhereSql(params) {
    StringBuffer sql = new StringBuffer()
    def positionalParams = []
    String alias = params.property.substring(0, 1).toLowerCase()
    sql.append("from " + params.property + " as " + alias + " where 1=1 ")
    def es = params.entrySet().sort {it.key}.sort()
    es.each {
      if (!CheckUtils.isEmpty(it.value)) {
        String[] results = it.key.split("_")
        if (results.length == 2) {
          String prefix = results[0].substring(1)
          String operator
          Object param
          if ("lk" == prefix || "sl" == prefix || "el" == prefix) {
            operator = " like ?  "
            param = DynamicService.escapeLike(it.value)
            // like
            if ("lk" == prefix) {
              param = "%" + escapeLike(param) + "%"
              // start like
            } else if ("sl" == prefix) {
              param = "%" + escapeLike(param)
              // end like
            } else if ("el" == prefix) {
              param = escapeLike(param) + "%"
            }
          } else {
            param = it.value
            if ("eq" == prefix) {
              operator = "=? "
            } else if ("ne" == prefix) {
              operator = "<>? "
            } else if ("gt" == prefix) {
              operator = ">? "
            } else if ("lt" == prefix) {
              operator = "<? "
            } else if ("ge" == prefix) {
              operator = ">=? "
            } else if ("le" == prefix) {
              operator = "<=? "
            }
          }
          sql.append("and " + alias + "." + results[1] + operator)
          positionalParams.add(param)
        } else if (results.length == 3) {

          String prefix = results[0].substring(1)
          String operator
          def param = it.value
          SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd")
          param = sd.parse(param)
          // Date  param=new java.sql.Date(Date.parse(bparam))
          if ("ge" == prefix) {
            operator = ">=? "
          } else if ("le" == prefix) {
            operator = "<=? "
          }

          sql.append("and " + alias + "." + results[1] + operator)
          positionalParams.add(param)

        }
      }
    }
    return ["sql": sql.toString(), "positionalParams": positionalParams]
  }
}
